package com.yonyou.crm.common.field.relation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * example 
 * 假设是用户上的部门字段
 * new FieldRelation<UserVO>(UserVO.class, "deptId", orgService, "selectFieldsByIds", new String[]{"deptName"})
 * @author litcb
 *
 */
public class RefFieldRelation<T> extends FieldRelation<T> {
	
	//查询该项使用的方法
	private String method = "selectFieldsByIds";
	//查询到的值，覆写entity上的哪些字段
	protected String[] writeFields;

	/**
	 * 构造方法
	 * @param clazz 要更改的类
	 * @param readField 要读取的字段
	 * @param writeFields 要写入的字段
	 * @param service 要查询的服务
	 * @param method 要查询的方法
	 */
	public RefFieldRelation(Class<T> clazz,String readField, String[] writeFields, Object service, String method) {
		super();
		this.clazz = clazz;
		this.readField = readField;
		this.service = service;
		this.method = method;
		this.writeFields = writeFields;
	}

	@Override
	public List<T> handle(List<T> vos) {
		
		if (vos == null || vos.size() == 0) {
			return vos;
		}
		
		try {
			Field getField = clazz.getDeclaredField(readField);
			getField.setAccessible(true);
			Set<Object> keys = new HashSet<Object>();

			for (T vo : vos) {
				if (vo != null && getField.get(vo) != null) {
					keys.add(getField.get(vo));
				}
			}
			
			Object[] paraValues = keys.toArray(new Object[0]);
			
			if (paraValues == null || paraValues.length == 0) {
				return vos;
			}
			
			Class<?>[] paraTypes = new Class[]{Object[].class};
			Method selectFieldsByIds = service.getClass().getMethod(method, paraTypes);
			//调服务查询结果
			@SuppressWarnings("unchecked")
			List<Map<String, Object>> valueList =  (List<Map<String, Object>>)selectFieldsByIds.invoke(service, new Object[]{paraValues});
			
			if(valueList == null) {
				return vos;
			}
			
			//转换结果集
			Map<String, Object[]> valueMap = new HashMap<String, Object[]>();
			for (Map<String, Object> valueObj : valueList) {
				
				Object[] valueArray = new Object[writeFields.length];
				for (int i=0; i<writeFields.length; i++) {
					//回写字段只有一个时，key为name
					if (writeFields.length == 1) {
						valueArray[i] = valueObj.get(Name);
					}
					//有多个时，按照回写字段的个数，key为name1、name2、name3...
					else {
						valueArray[i] = valueObj.get(Name + (i+1));
					}
					
				}
				valueMap.put(valueObj.get(Id).toString(), valueArray);
			}

			//设置回写字段集合
			Field[] writeFieldArray = new Field[writeFields.length];
			for(int i=0; i<writeFields.length; i++) {
				Field writeField = clazz.getDeclaredField(writeFields[i]);
				writeField.setAccessible(true);
				writeFieldArray[i] = writeField;
			}

			//回写字段赋值
			for (T vo : vos) {
				
				for(int i=0; i<writeFieldArray.length; i++) {
					
					Object valueKeyObj = getField.get(vo);
					if (valueKeyObj != null) {
						
						Object[] valueArray = valueMap.get(valueKeyObj.toString());
						if (valueArray != null && valueArray.length > i) {
							
							writeFieldArray[i].set(vo, valueArray[i]);
						}
						
					}
				}
			}
			
		} catch (Exception e) {} 
		
		return vos;
	}

}
